home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
programr
/
rsxwdk2s.zip
/
RSXWDK
/
LIBSRC
/
WIN
/
SELECTOR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-05
|
4KB
|
229 lines
#include <sys/rsxw32.h>
#ifdef __OPTIMIZE__
#define INLINE static inline
#else
#define INLINE static
#endif
#define CHECKERR "jnc 1f\n\tmovl $-1, %0 \n\tjmp 2f \n\t1: \n\t"
#define CHECKERR0 "jnc 1f\n\tmovl $0, %0 \n\tjmp 2f \n\t1: \n\t"
#define CHECK_ERR_DPMI10 "jc 2f\n\t"
#define OKEAX0 "xorl %0, %0 \n\t2: \n\t"
#define END "2: \n\t"
/*
** DPMI functions
*/
/* return selector or null */
INLINE int AllocLDT(int n_sel)
{
register unsigned int _v;
__asm__ __volatile__(
"call _dpmi31 \n\t"
CHECKERR0
"movzwl %%ax, %0\n\t"
END
: "=a" (_v)
: "c" (n_sel) , "0" (0x000)
: "ax","cx" );
return _v ;
}
INLINE int FreeLDT(int sel)
{
register int _v;
__asm__ __volatile__(
"call _dpmi31 \n\t"
CHECKERR
OKEAX0
: "=a" (_v)
: "b" (sel) , "0" (0x001)
: "ax","bx" );
return _v ;
}
/* return base address or null */
INLINE unsigned int GetBaseAddress(int sel)
{
register unsigned int _v;
__asm__ __volatile__(
"call _dpmi31 \n\t"
CHECKERR0
"shll $16, %%ecx \n\t"
"movw %%dx, %%cx \n\t"
"movl %%ecx, %0 \n\t"
END
: "=a" (_v)
: "b" (sel) , "0" (0x006)
: "ax","bx","cx","dx" );
return _v ;
}
INLINE int SetBaseAddress(int sel, unsigned int base)
{
register int _v;
__asm__ __volatile__(
"call _dpmi31 \n\t"
CHECKERR
OKEAX0
: "=a" (_v)
: "b" (sel),"c" ((unsigned short)(base>>16)),
"d" ((unsigned short)base),"0" (0x007)
: "ax","bx","cx","dx" );
return _v ;
}
INLINE int SetLimit(int sel, unsigned int limit)
{
register int _v;
__asm__ __volatile__(
"call _dpmi31 \n\t"
CHECKERR
OKEAX0
: "=a" (_v)
: "b" (sel),"c" ((unsigned short)(limit>>16)),
"d" ((unsigned short)limit),"0" (0x008)
: "ax","bx","cx","dx" );
return _v ;
}
/*
INLINE unsigned short get_data_seg(void)
{
register unsigned short v;
__asm__("mov %%ds, %0 \n\t"
: "=r" ((unsigned short) v) );
return v;
}
*/
/* these selectors are needed for thunking */
#define N_SEL 5
static int _sys_sel[N_SEL];
/*
** init / free selectors
*/
static int init_selector(int * sel)
{
if (!(*sel = AllocLDT(1)))
return -1;
if (SetLimit(*sel, 0xFFFF)) {
FreeLDT(*sel);
return -1;
}
else
return 0;
}
int _sys_init_selectors(void)
{
int i;
int ret = 0;
for (i=0; i<N_SEL; i++)
ret |= init_selector(_sys_sel + i);
return ret;
}
static int free_selector(int sel)
{
return FreeLDT(sel);
}
int _sys_free_selectors(void)
{
int i;
int ret = 0;
for (i=0; i<N_SEL; i++)
ret |= free_selector(_sys_sel[i]);
return ret;
}
/*
* program layout:
* for each 64KB one selector with limit 0xFFFFF
*
* 0--------1--------2---------------------- n * 64 KB
* | | sel1,2 | sel3,4 | ... |
* 0----------------------------------------
*
*/
/*
* convert selectors
*/
ULONG _rsx_32to16(void *pointer32)
{
static int sel_index = 0;
if (!pointer32) /* NULL Parameter */
return 0;
else if ((ULONG)pointer32 <= 0xFFFF) /* MAKEINTRESOURCE */
return (ULONG) pointer32;
else if ((int)pointer32 <= _sys_last_addr) { /* take sel from rsxw32 */
ULONG off = (int) pointer32;
ULONG sel;
off -= 0x10000L; /* sub empty region */
sel = _sys_first_sel + ((off >> 15) << 3); /* index of sel * 8 */
return ((sel << 16) | (off & 0x7FFF));
}
sel_index ++ ;
if (sel_index >= N_SEL)
sel_index = 0;
if (SetBaseAddress(_sys_sel[sel_index], (ULONG)pointer32 + _sys_base_addr))
return 0;
else
return _sys_sel[sel_index] << 16;
}
void * _rsx_16to32(unsigned long farp)
{
unsigned long linaddr;
linaddr = GetBaseAddress(farp >> 16) + (farp & 0xFFFF);
return (void *) (linaddr - _sys_base_addr);
}
/*
** return 16bit stack
** convert value x to sel : x & 0xFFFF
*/
ULONG _rsx_stack16_sel(void *pointer32)
{
ULONG off = (int) pointer32;
ULONG sel;
off -= 0x10000L;
sel = _sys_first_sel + ((off >> 15) << 3);
off &= 0xFFFF;
if (off > 0x7FFF)
sel += 8;
return (sel);
}